package com.VolunteerPlatform.SecurityService;


import com.VolunteerPlatform.Entity.AdminInfo;
import com.VolunteerPlatform.Entity.AdminRoleInfo;
import com.VolunteerPlatform.Service.AdminService.AdminInfoService;
import com.VolunteerPlatform.Service.AdminService.AdminRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.cache.NullUserCache;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by DoveXL on 2018/5/30.
 */
@Service
public class MyUserDetailsService implements UserDetailsService{

        @Autowired
        private AdminRoleService adminRoleService;

       @Autowired(required = false)
        private AdminInfoService adminInfoService;

        private UserCache userCache = new NullUserCache();

    @Override
        public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
            AdminInfo user;
            System.out.println(userName);
            try {
                user = adminInfoService.findAdminByNameService(userName);
            } catch (Exception e) {
                e.printStackTrace();
                throw new UsernameNotFoundException("User Selected Failed");
            }
            if(user == null){
                throw new UsernameNotFoundException("No User Found");
            } else {
                try {
                    List<AdminRoleInfo> roles = adminRoleService.findByUserNameService(user.getUserName());
                    return new UserRoleDetails(user, roles);
                } catch (Exception e) {
                    throw new UsernameNotFoundException("User Role Selected Failed");
                }
            }
        }


        public int changePassword(String username,String newpassword,String oldpassword)
        {
            Authentication currentuser= SecurityContextHolder.getContext().getAuthentication();
            if(currentuser==null)
            {
                // This would indicate bad coding somewhere
                throw new AccessDeniedException("Can't change password as no Authentication object found in context " +
                        "for current user.");
            }
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String username2=((UserDetails)principal).getUsername();
            AdminInfo userLogin = adminInfoService.findAdminByNameService(username2);
            if(oldpassword.equals(userLogin.getPassword()))
            {
                userLogin.setPassword(newpassword);
                int ResultNumber =adminInfoService.updateAdminInfoService(username2,null,newpassword,null);
                SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(currentuser, newpassword));
                userCache.removeUserFromCache(username);
                return ResultNumber;
            }else
            {
                return -1;
            }
        }

       public Authentication createNewAuthentication(Authentication currentAuth, String newPassword)
       {
        UserDetails user = loadUserByUsername(currentAuth.getName());

        UsernamePasswordAuthenticationToken newAuthentication =
                new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
        newAuthentication.setDetails(currentAuth.getDetails());

        return newAuthentication;
        }



}
